import type { PageType } from '../../../../../lib/page_handler/type'
import type { GreasyForkElements } from '../../../../../types/constants/personalization/greasy_fork'
import type {
  ComponentStyleIdType,
  PlatformTypeValue,
} from '../../../../../types/interfaces'
import { BaseModule } from '../../../../../lib/abstract'
import { PageHandler } from '../../../../../lib/page_handler'
import { GreasyForkPageType } from '../../../../../lib/page_handler/platform/greasyfork/types'
import {
  ComponentStyleId,
  HOSTNAME,
  logger,
  PAGE_ELEMENTS,
  SUPPORTED_PLATFORMS,
} from '../../../../../types/constants'
import { ConfigManager } from '../../../../config_manager'

interface TimeFormatConfig {
  /** 容器选择器 */
  containerSelector: string
  /** 时间元素选择器 */
  timeElementSelector: string
  // /** 是否启用精确时间格式 */
  // preciseFormat?: boolean
  // /** 自定义时间格式 (可选) */
  // customFormat?: string // 如 'YYYY/MM/DD HH:mm:ss'
}

type PageTimeFormatConfig = Partial<Record<string, TimeFormatConfig>>
type PlatformTimeFormatConfig = Partial<Record<PlatformTypeValue, PageTimeFormatConfig>>

interface Config {
  enabled?: boolean
}

export class GreasyForkTimeHelper extends BaseModule {
  readonly id: string = 'greasy_fork_timestamp_enhancement'
  readonly styleId: string = ComponentStyleId[this.name]
  isInitialized: boolean = false
  readonly supportedPlatforms: string[] = ConfigManager.getInstance().moduleSupportedPlatforms(this.name)
  private static instance: GreasyForkTimeHelper
  private pageHandler: PageHandler = PageHandler.getInstance()
  elements: GreasyForkElements = PAGE_ELEMENTS[SUPPORTED_PLATFORMS.GREASY_FORK]
  private readonly timeFormatConfigs: PlatformTimeFormatConfig = {}
  private currentPageType: PageType | null = null

  config: Config = {
    enabled: true,
  }

  get name(): ComponentStyleIdType {
    return 'GreasyForkTimeHelper'
  }

  constructor() {
    super()

    this.timeFormatConfigs = {
      [SUPPORTED_PLATFORMS.GREASY_FORK]: {
        [GreasyForkPageType.SCRIPT_FEEDBACK]: {
          containerSelector: '#script-info .discussion-list-container',
          timeElementSelector: '.discussion-meta-item relative-time',
        },
        [GreasyForkPageType.SCRIPT_DISCUSSION]: {
          containerSelector: '#script-info .comment',
          timeElementSelector: '.comment-meta relative-time',
        },
        [GreasyForkPageType.DISCUSSIONS]: {
          containerSelector: '.discussion-list .discussion-list-container',
          timeElementSelector: '.discussion-meta-item relative-time',
        },
        // 测试链接：https://greasyfork.org/zh-CN/discussions/greasyfork/303215
        [GreasyForkPageType.DISCUSSIONS_DETAIL]: {
          containerSelector: '.text-content .comment',
          timeElementSelector: '.comment-meta relative-time',
        },
      },
    }
  }

  /**
   * 获取单例实例
   */
  public static getInstance(): GreasyForkTimeHelper {
    if (!GreasyForkTimeHelper.instance) {
      GreasyForkTimeHelper.instance = new GreasyForkTimeHelper()
    }
    return GreasyForkTimeHelper.instance
  }

  handleCleanupReferences(): void {
    // 1. 清除数据
    this.currentPageType = null
  }

  handleCleanupCreatedElements(): void {
    // 1. 移除所有添加的元素
    $('.gf-time-helper').remove()
  }

  core(): void {
    this.loadConfig()

    if (!this.config.enabled)
      return

    this.formatTime()
  }

  onToggleCallback(_id: string, checked: boolean): void {
    super.onToggleCallback(_id, checked)
  }

  private formatTime(): void {
    this.currentPageType = PageHandler.getCurrentPageType()

    const platformConfig = this.timeFormatConfigs[HOSTNAME]
    if (!platformConfig)
      return

    const config = platformConfig[this.currentPageType]
    if (!config)
      return

    this.pageHandler.services.greasyFork.formatAllTimes(
      config.containerSelector,
      config.timeElementSelector,
    )
  }

  applyConfig(config: Partial<Config>): void {
    super.updateConfig(config)

    this.formatTime()

    logger.info(`[${this.name}] Config updated and apply`, this.config)
  }

  getStyles(): string {
    return ``
  }
}
